package cn.com.dhcc.turbo.service.registry.sync.mina;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.base.IocBean;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.remotehandler.socket.ICallBack;
import cn.com.dhcc.app.core.handler.remotehandler.socket.ISendDataClient;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.tag.CommonStaticCode.SUCCESSFAIL;
import cn.com.dhcc.app.pub.core.consts.AppIocBean;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.registry.NodePipeline;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncOperType;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncStatus;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncType;
import cn.com.dhcc.turbo.service.registry.NodeInfoService;
import cn.com.dhcc.turbo.service.registry.sync.ISyncSender;
import cn.com.dhcc.turbo.service.registry.sync.SyncCallBack;
import cn.com.dhcc.turbo.service.registry.sync.SynchronizeHandler;
import cn.com.dhcc.turbo.service.registry.vo.NodeRegistSyncData;
/**
 * socket 同步方式
 * @author qiao
 * @2014-8-26 @下午2:44:20
 */
@Service(AppIocBean.SYNC_SENDER_SOCKET_IMPL)
public class SyncSenderSocketImpl implements ISyncSender {

	@Autowired
	@Qualifier(IocBean.MINA_SOCKET_SEND_DATA_CLIENT)
	ISendDataClient sendDataClient;
	@Autowired
	SynchronizeHandler synchronizeHandler;
	@Autowired
	NodeInfoService nodeInfoService;
	
	private String ip;
	private int port; 
	
	@SuppressWarnings("deprecation")
	private static Logger logger = Log.getExistLogger(LOGTYPE.SYNC);
	/**
	 * syncUrl --> ip:port
	 */
	
	public void analyseSyncUrl(String syncUrl) {
		String[] ip_port = syncUrl.split(":");
		ip = ip_port[0];
		port = Integer.parseInt(ip_port[1]);
	}

	/**
	 * @throws Exception 
	 * 
	 */
	@Override
	public SyncCallBack sendData( String syncUrl,final SynchronizeInfo synchronizeInfo) throws Exception {
		analyseSyncUrl(syncUrl);
		final String dataType = synchronizeInfo.getDataType();
		final SyncCallBack backMsg = new SyncCallBack();
		logger.info("开始同步["+AppTagEl.getNameFromCode(SyncType.class, synchronizeInfo.getDataType())
				   +"]信息给节点["+synchronizeInfo.getToNodeName()+"]");
		//发送
		sendDataClient.sendData(ip, port, synchronizeInfo, new ICallBack() {
			@Override
			public void recevieCallBackData(Object callBackData) {
				SyncCallBack callBack = (SyncCallBack)callBackData;
				SUCCESSFAIL status = callBack.getResult();
				//失败
				if(status.getStatus().equals(SUCCESSFAIL.FAIL.getStatus())){
					synchronizeInfo.setStatus(SyncStatus.FAIL.getCode());
					synchronizeInfo.setRemark(callBack.getMsg());
					backMsg.setResult(SUCCESSFAIL.FAIL);
					if(SyncType.NODE_REGIST.getCode().equalsIgnoreCase(dataType)){//处理节点注册的返回
						backMsg.setMsg("节点注册失败,"+callBack.getMsg());
					}else{
						try {
							synchronizeHandler.insertOrUpdateSynchronizeInfo(synchronizeInfo);
						} catch (ServiceException e) {
							//这一步不能失败
						}
					}
				}else{
					logger.info("同步["+AppTagEl.getNameFromCode(SyncType.class, synchronizeInfo.getDataType())
							   +"]信息给节点["+synchronizeInfo.getToNodeName()+"]成功");
					backMsg.setResult(SUCCESSFAIL.SUCCESS);
					synchronizeInfo.setStatus(SyncStatus.SUCCESS.getCode());
					if(SyncType.NODE_REGIST.getCode().equalsIgnoreCase(dataType)){//处理节点注册的返回
						//接收注册节点返回来的通道信息
						NodeRegistSyncData nodeRegistSyncData = (NodeRegistSyncData) callBack.getNodeRegistSyncData();
						List<NodePipeline> remoteNodePipeLines = nodeRegistSyncData.getAllPipeInfos();
						synchronizeHandler.setNodesPipeLinesToUnLocalFlag(remoteNodePipeLines, null);
						NodeInfo registNode = nodeRegistSyncData.getRegistNode();
						try {
							nodeInfoService.insert(nodeRegistSyncData.getRegistNode());
							synchronizeHandler.insertOrUpdateSyncPipeLineInfo(remoteNodePipeLines);
							//开始全网同步，已注册的节点和节点的通道信息
							synchronizeHandler.syncToAllNodes(SyncType.NODE_INFO, false,registNode,registNode, nodeRegistSyncData.getRegistNode(), SyncOperType.INSERT,true);
							synchronizeHandler.syncToAllNodes(SyncType.PILE_LINE_LIST, false,registNode,registNode, remoteNodePipeLines, SyncOperType.INSERT,true);
						} catch (ServiceException e) {
							backMsg.setResult(SUCCESSFAIL.FAIL);
							backMsg.setMsg("节点注册失败");
						}catch (NiceException e) {
							//节点同步失败
						}
					}else{
						try {
							synchronizeHandler.insertOrUpdateSynchronizeInfo(synchronizeInfo);
						} catch (ServiceException e) {
							//这一步不能失败
						}
					}
				}
			}
			@Override
			public void onException(Throwable cause){
				synchronizeInfo.setStatus(SyncStatus.FAIL.getCode());
				backMsg.setResult(SUCCESSFAIL.FAIL);
				synchronizeInfo.setRemark(cause.getMessage());
				if(SyncType.NODE_REGIST.getCode().equalsIgnoreCase(dataType)){//处理节点注册的返回
					backMsg.setMsg("节点注册失败,"+cause.getMessage());
				}else{
					try {
						synchronizeHandler.insertOrUpdateSynchronizeInfo(synchronizeInfo);
					} catch (ServiceException e) {
						//这一步不能失败
					}
				}
			}
		});
		return backMsg;
	}
	public boolean syncUrlIsValid(String syncUrl){
		SynchronizeInfo synchronizeInfo = new SynchronizeInfo();
		synchronizeInfo.setDataType(SyncType.TEST_CONNECT.getCode());
		try {
			SyncCallBack callBack = sendData(syncUrl,synchronizeInfo);
			if(callBack!=null&&callBack.getResult()==SUCCESSFAIL.SUCCESS){
				return true;
			}
		} catch (Exception e) {
		}
		return false;
	}
	
}
